<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas环形进度条</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            color: #fff;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }
        
        .container {
            width: 100%;
            max-width: 800px;
            margin: 0 auto;
            background: rgba(0, 0, 0, 0.7);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            text-align: center;
        }
        
        h1 {
            margin-bottom: 30px;
            color: #fdbb2d;
            text-shadow: 0 0 10px rgba(253, 187, 45, 0.5);
            font-size: 2.5rem;
        }
        
        .description {
            margin-bottom: 40px;
            line-height: 1.6;
            color: #e1e1e1;
            max-width: 600px;
            margin-left: auto;
            margin-right: auto;
        }
        
        .canvas-container {
            position: relative;
            width: 300px;
            height: 300px;
            margin: 0 auto 30px;
        }
        
        canvas {
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.4);
            box-shadow: 0 0 30px rgba(0, 0, 0, 0.6);
        }
        
        .progress-info {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            color: #fff;
        }
        
        .progress-value {
            font-size: 3rem;
            font-weight: bold;
            color: #fdbb2d;
            text-shadow: 0 0 10px rgba(253, 187, 45, 0.5);
        }
        
        .progress-text {
            font-size: 1.2rem;
            margin-top: 5px;
        }
        
        .controls {
            display: flex;
            gap: 15px;
            margin-bottom: 30px;
            flex-wrap: wrap;
            justify-content: center;
        }
        
        .btn {
            padding: 12px 25px;
            border: none;
            border-radius: 50px;
            font-family: 'Segoe UI', sans-serif;
            font-weight: bold;
            font-size: 1rem;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .btn-start {
            background: linear-gradient(135deg, #00b09b, #96c93d);
            color: white;
        }
        
        .btn-pause {
            background: linear-gradient(135deg, #ff9966, #ff5e62);
            color: white;
        }
        
        .btn-reset {
            background: linear-gradient(135deg, #8e2de2, #4a00e0);
            color: white;
        }
        
        .btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }
        
        .btn:active {
            transform: translateY(0);
        }
        
        .custom-controls {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            justify-content: center;
            margin-bottom: 30px;
        }
        
        .control-group {
            display: flex;
            flex-direction: column;
            align-items: center;
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
            min-width: 180px;
        }
        
        .control-label {
            margin-bottom: 10px;
            font-weight: 500;
            color: #fdbb2d;
        }
        
        .slider-container {
            display: flex;
            align-items: center;
            gap: 10px;
            width: 100%;
        }
        
        input[type="range"] {
            flex: 1;
            height: 8px;
            -webkit-appearance: none;
            appearance: none;
            background: linear-gradient(90deg, #00b09b, #96c93d);
            border-radius: 4px;
            outline: none;
        }
        
        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: #fdbb2d;
            cursor: pointer;
            box-shadow: 0 0 10px rgba(253, 187, 45, 0.5);
        }
        
        .slider-value {
            font-weight: bold;
            min-width: 40px;
            text-align: center;
        }
        
        .color-picker {
            display: flex;
            gap: 10px;
            justify-content: center;
            flex-wrap: wrap;
        }
        
        .color-option {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            cursor: pointer;
            border: 2px solid transparent;
            transition: all 0.3s ease;
        }
        
        .color-option:hover {
            transform: scale(1.2);
        }
        
        .color-option.active {
            border-color: white;
            box-shadow: 0 0 10px white;
        }
        
        .tips {
            margin-top: 30px;
            padding: 15px;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 10px;
            font-size: 0.9rem;
            line-height: 1.6;
        }
        
        .tips h3 {
            margin-bottom: 10px;
            color: #fdbb2d;
        }
        
        @media (max-width: 600px) {
            .container {
                padding: 20px;
            }
            
            h1 {
                font-size: 2rem;
            }
            
            .canvas-container {
                width: 250px;
                height: 250px;
            }
            
            .progress-value {
                font-size: 2.5rem;
            }
            
            .btn {
                padding: 10px 20px;
                font-size: 0.9rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1><i class="fas fa-circle-notch"></i> Canvas环形进度条</h1>
        
        <p class="description">
            使用HTML5 Canvas实现的环形进度条，支持动画效果、进度控制和颜色自定义。
        </p>
        
        <div class="canvas-container">
            <canvas id="progressCanvas" width="300" height="300"></canvas>
            <div class="progress-info">
                <div class="progress-value">0%</div>
                <div class="progress-text">完成进度</div>
            </div>
        </div>
        
        <div class="controls">
            <button class="btn btn-start" id="startBtn">
                <i class="fas fa-play"></i> 开始
            </button>
            <button class="btn btn-pause" id="pauseBtn">
                <i class="fas fa-pause"></i> 暂停
            </button>
            <button class="btn btn-reset" id="resetBtn">
                <i class="fas fa-redo"></i> 重置
            </button>
        </div>
        
        <div class="custom-controls">
            <div class="control-group">
                <div class="control-label">进度值</div>
                <div class="slider-container">
                    <input type="range" id="progressSlider" min="0" max="100" value="75">
                    <span class="slider-value" id="progressValue">75%</span>
                </div>
            </div>
            
            <div class="control-group">
                <div class="control-label">动画速度</div>
                <div class="slider-container">
                    <input type="range" id="speedSlider" min="1" max="10" value="5">
                    <span class="slider-value" id="speedValue">5</span>
                </div>
            </div>
            
            <div class="control-group">
                <div class="control-label">线条宽度</div>
                <div class="slider-container">
                    <input type="range" id="widthSlider" min="5" max="30" value="15">
                    <span class="slider-value" id="widthValue">15</span>
                </div>
            </div>
        </div>
        
        <div class="control-group" style="margin: 0 auto 30px; max-width: 400px;">
            <div class="control-label">进度条颜色</div>
            <div class="color-picker">
                <div class="color-option active" style="background: #fdbb2d;" data-color="#fdbb2d"></div>
                <div class="color-option" style="background: #00b09b;" data-color="#00b09b"></div>
                <div class="color-option" style="background: #8e2de2;" data-color="#8e2de2"></div>
                <div class="color-option" style="background: #ff5e62;" data-color="#ff5e62"></div>
                <div class="color-option" style="background: #36d1dc;" data-color="#36d1dc"></div>
                <div class="color-option" style="background: #ff8c00;" data-color="#ff8c00"></div>
            </div>
        </div>
        
        <div class="tips">
            <h3><i class="fas fa-lightbulb"></i> 使用提示</h3>
            <p>1. 使用滑块调整目标进度值，然后点击开始按钮查看动画效果</p>
            <p>2. 可以调整动画速度和线条宽度以获得不同的视觉效果</p>
            <p>3. 选择不同的颜色选项可以改变进度条的外观</p>
            <p>4. 进度条会在达到目标值时自动停止</p>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const canvas = document.getElementById('progressCanvas');
            const ctx = canvas.getContext('2d');
            const progressValue = document.querySelector('.progress-value');
            const progressSlider = document.getElementById('progressSlider');
            const progressValueDisplay = document.getElementById('progressValue');
            const speedSlider = document.getElementById('speedSlider');
            const speedValue = document.getElementById('speedValue');
            const widthSlider = document.getElementById('widthSlider');
            const widthValue = document.getElementById('widthValue');
            const startBtn = document.getElementById('startBtn');
            const pauseBtn = document.getElementById('pauseBtn');
            const resetBtn = document.getElementById('resetBtn');
            const colorOptions = document.querySelectorAll('.color-option');
            
            let progress = 0;
            let targetProgress = 75;
            let animationSpeed = 5;
            let lineWidth = 15;
            let progressColor = '#fdbb2d';
            let isAnimating = false;
            let animationId = null;
            
            // 初始化
            function init() {
                progressSlider.value = targetProgress;
                progressValueDisplay.textContent = `${targetProgress}%`;
                speedSlider.value = animationSpeed;
                speedValue.textContent = animationSpeed;
                widthSlider.value = lineWidth;
                widthValue.textContent = lineWidth;
                drawProgress();
            }
            
            // 绘制进度条
            function drawProgress() {
                const centerX = canvas.width / 2;
                const centerY = canvas.height / 2;
                const radius = Math.min(centerX, centerY) - lineWidth;
                
                // 清除画布
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                
                // 绘制背景圆
                ctx.beginPath();
                ctx.arc(centerX, centerY, radius, 0, Math.PI * 2, false);
                ctx.lineWidth = lineWidth;
                ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
                ctx.stroke();
                
                // 绘制进度圆
                const startAngle = -Math.PI / 2; // 从顶部开始
                const endAngle = startAngle + (Math.PI * 2 * progress / 100);
                
                ctx.beginPath();
                ctx.arc(centerX, centerY, radius, startAngle, endAngle, false);
                ctx.lineWidth = lineWidth;
                ctx.strokeStyle = progressColor;
                ctx.lineCap = 'round';
                ctx.stroke();
                
                // 更新进度文本
                progressValue.textContent = `${Math.round(progress)}%`;
            }
            
            // 动画函数
            function animate() {
                if (isAnimating) {
                    if (progress < targetProgress) {
                        progress += animationSpeed / 10;
                        if (progress > targetProgress) progress = targetProgress;
                    } else if (progress > targetProgress) {
                        progress -= animationSpeed / 10;
                        if (progress < targetProgress) progress = targetProgress;
                    } else {
                        isAnimating = false;
                        cancelAnimationFrame(animationId);
                        return;
                    }
                    
                    drawProgress();
                    animationId = requestAnimationFrame(animate);
                }
            }
            
            // 开始动画
            function startAnimation() {
                if (!isAnimating) {
                    isAnimating = true;
                    animate();
                }
            }
            
            // 暂停动画
            function pauseAnimation() {
                isAnimating = false;
                if (animationId) {
                    cancelAnimationFrame(animationId);
                }
            }
            
            // 重置进度
            function resetProgress() {
                pauseAnimation();
                progress = 0;
                drawProgress();
            }
            
            // 事件监听
            startBtn.addEventListener('click', startAnimation);
            pauseBtn.addEventListener('click', pauseAnimation);
            resetBtn.addEventListener('click', resetProgress);
            
            progressSlider.addEventListener('input', function() {
                targetProgress = parseInt(this.value);
                progressValueDisplay.textContent = `${targetProgress}%`;
                if (!isAnimating) {
                    progress = targetProgress;
                    drawProgress();
                }
            });
            
            speedSlider.addEventListener('input', function() {
                animationSpeed = parseInt(this.value);
                speedValue.textContent = animationSpeed;
            });
            
            widthSlider.addEventListener('input', function() {
                lineWidth = parseInt(this.value);
                widthValue.textContent = lineWidth;
                drawProgress();
            });
            
            colorOptions.forEach(option => {
                option.addEventListener('click', function() {
                    colorOptions.forEach(opt => opt.classList.remove('active'));
                    this.classList.add('active');
                    progressColor = this.getAttribute('data-color');
                    drawProgress();
                });
            });
            
            // 初始化
            init();
            
            // 响应窗口大小变化
            window.addEventListener('resize', function() {
                drawProgress();
            });
        });
    </script>
</body>
</html>